home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / ip / dns / resolv+2.1.1 / mktemp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-28  |  2.4 KB  |  113 lines

  1. /*
  2.  * Copyright (c) 1987 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #if defined(LIBC_SCCS) && !defined(lint)
  19. static char sccsid[] = "@(#)mktemp.c    5.8 (Berkeley - modified) 10/16/89";
  20. #endif /* LIBC_SCCS and not lint */
  21.  
  22. #include <sys/types.h>
  23. #include <sys/file.h>
  24. #include <sys/stat.h>
  25. #include <errno.h>
  26. #include <stdio.h>
  27. #include <ctype.h>
  28.  
  29. #ifndef S_ISDIR
  30. #define S_ISDIR(m)    ((m & 0170000) == 0040000)
  31. #endif
  32.  
  33. mkstemp(path)
  34.     char *path;
  35. {
  36.     int fd;
  37.  
  38.     return (_gettemp(path, &fd) ? fd : -1);
  39. }
  40.  
  41. char *
  42. mktemp(path)
  43.     char *path;
  44. {
  45.     return(_gettemp(path, (int *)NULL) ? path : (char *)NULL);
  46. }
  47.  
  48. static
  49. _gettemp(path, doopen)
  50.     char *path;
  51.     register int *doopen;
  52. {
  53.     extern int errno;
  54.     register char *start, *trv;
  55.     struct stat sbuf;
  56.     u_int pid;
  57.  
  58.     pid = getpid();
  59.     for (trv = path; *trv; ++trv);        /* extra X's get set to 0's */
  60.     while (*--trv == 'X') {
  61.         *trv = (pid % 10) + '0';
  62.         pid /= 10;
  63.     }
  64.  
  65.     /*
  66.      * check the target directory; if you have six X's and it
  67.      * doesn't exist this runs for a *very* long time.
  68.      */
  69.     for (start = trv + 1;; --trv) {
  70.         if (trv <= path)
  71.             break;
  72.         if (*trv == '/') {
  73.             *trv = '\0';
  74.             if (stat(path, &sbuf))
  75.                 return(0);
  76.             if (!S_ISDIR(sbuf.st_mode)) {
  77.                 errno = ENOTDIR;
  78.                 return(0);
  79.             }
  80.             *trv = '/';
  81.             break;
  82.         }
  83.     }
  84.  
  85.     for (;;) {
  86.         if (doopen) {
  87.             if ((*doopen =
  88.                 open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
  89.                 return(1);
  90.             if (errno != EEXIST)
  91.                 return(0);
  92.         }
  93.         else if (stat(path, &sbuf))
  94.             return(errno == ENOENT ? 1 : 0);
  95.  
  96.         /* tricky little algorithm for backward compatibility */
  97.         for (trv = start;;) {
  98.             if (!*trv)
  99.                 return(0);
  100.             if (*trv == 'z')
  101.                 *trv++ = 'a';
  102.             else {
  103.                 if (isdigit(*trv))
  104.                     *trv = 'a';
  105.                 else
  106.                     ++*trv;
  107.                 break;
  108.             }
  109.         }
  110.     }
  111.     /*NOTREACHED*/
  112. }
  113.